#include "..//Math/Tuple2.h"
#include "..//Math/Tuple3.h"
#include "Scene.h"
#include "..//StaticMesh.h"
#include <cuda_runtime.h>
#include "..//tinyXML//tinyxml.h"
#include <stdio.h>

cudaDeviceProp DeviceProp;

const cudaDeviceProp& GetDeviceProp()
{
	return DeviceProp;
}

CSceneManager::CSceneManager()
{
	pd_VertexBuffer = NULL;
	pd_VertexIndexBuffer = NULL;
	pd_KDTreeTriangleIndexBuffer = NULL;
	pd_KDopNodes = NULL;
	pd_ConstantData = NULL;
	ph_VertexBuffer = NULL;
	ph_VertexIndexBuffer = NULL;
	ph_KDTreeTriangleIndexBuffer = NULL;
	ph_KDopNodes = NULL;
	for(int i=0; i<10; ++i)
	{
		pd_VertexIndexTexture[i] = NULL;
		pd_TriangleIndexTexture[i] = NULL;
	}
}

bool InitCUDA(void)
{
        int count = 0;
        int i = 0;

        cudaGetDeviceCount(&count);
        if(count == 0)
		{
                fprintf(stderr, "There is no device.\n");
                return false;
        }

        for(i = 0; i < count; i++)
		{
               // cudaDeviceProp prop;
                if(cudaGetDeviceProperties(&DeviceProp, i) == cudaSuccess) 
				{
                        if(DeviceProp.major >= 1) 
						{
                                break;
                        }
                }
        }
        if(i == count)
		{
                fprintf(stderr, "There is no device supporting CUDA 1.x.\n");
                return false;
        }
        cudaSetDevice(i);
        return true;
}

void DumpRes(const char* pFileName, const unsigned char* pData, int DataSize)
{
	FILE* pDumpFile = fopen(pFileName, "wb");
	if(pDumpFile)
	{
		fwrite(pData, DataSize, 1, pDumpFile);
		fclose(pDumpFile);
	}
}

void CSceneManager::PrepareDeviceData()
{
	//fill pd_VertexBuffer
	cudaMalloc((void**)&pd_VertexBuffer, sizeof(CVertex)*VertexCount);
	cudaMemcpy(pd_VertexBuffer, ph_VertexBuffer, sizeof(CVertex)*VertexCount, cudaMemcpyHostToDevice);
	//release host resource
	SAFE_DELETE_ARRAY(ph_VertexBuffer);

	////fill pd_VertexIndexBuffer
	//cudaMalloc((void**)&pd_VertexIndexBuffer, sizeof(int)*VertexIndexCount);
	//cudaMemcpy(pd_VertexIndexBuffer, ph_VertexIndexBuffer, sizeof(int)*VertexIndexCount, cudaMemcpyHostToDevice);
	////release host resource
	//SAFE_DELETE_ARRAY(ph_VertexIndexBuffer);

	////fill pd_KDTreeTriangleIndexBuffer
	//cudaMalloc((void**)&pd_KDTreeTriangleIndexBuffer, sizeof(int)*VertexIndexCount/3);
	//cudaMemcpy(pd_KDTreeTriangleIndexBuffer, ph_KDTreeTriangleIndexBuffer, sizeof(int)*VertexIndexCount/3, cudaMemcpyHostToDevice);
	////release host resource
	//SAFE_DELETE_ARRAY(ph_KDTreeTriangleIndexBuffer);

	//fill pd_KDopNodes
	cudaMalloc((void**)&pd_KDopNodes, sizeof(CKDopNode)*KDopNodesCount);
	cudaMemcpy(pd_KDopNodes, ph_KDopNodes, sizeof(CKDopNode)*KDopNodesCount, cudaMemcpyHostToDevice);
	//release host resource
	SAFE_DELETE_ARRAY(ph_KDopNodes);
	
	//fill SceneRasterBufferElement
	for (int i=0; i<SceneRasterBufferElement.size(); ++i)
	{
		Tuple2i TextureSize = SceneStaticMeshes[i]->pInstance->TextureSize;
		RasterBufferElement* LocalRasterBuffer= NULL;
		cudaMalloc((void**)&LocalRasterBuffer, sizeof(RasterBufferElement)*TextureSize.x*TextureSize.y);
		cudaMemcpy(LocalRasterBuffer, SceneRasterBufferElement[i], sizeof(RasterBufferElement)*TextureSize.x*TextureSize.y, cudaMemcpyHostToDevice);
		d_SceneRasterBufferElement.push_back(LocalRasterBuffer);
		SAFE_DELETE_ARRAY(SceneRasterBufferElement[i]);

		unsigned char* pLightMap = NULL;
		cudaMalloc((void**)&pLightMap, sizeof(unsigned char)*TextureSize.x*TextureSize.y);
		d_LightMaps.push_back(pLightMap);

		unsigned char* ph_LightMap = NULL;
		ph_LightMap = (unsigned char*)malloc(sizeof(unsigned char)*TextureSize.x*TextureSize.y);
		memset(ph_LightMap, 0, sizeof(unsigned char)*TextureSize.x*TextureSize.y);
		cudaMemcpy(pLightMap, ph_LightMap, sizeof(unsigned char)*TextureSize.x*TextureSize.y, cudaMemcpyHostToDevice);
		SAFE_FREE(ph_LightMap);
	}
	SceneRasterBufferElement.clear();
}

void CSceneManager::LoadStaticMesh()
{
	for(int i=0; i<StaticMeshData.size(); ++i)
	{
		CStaticMesh* pMesh = new CStaticMesh;
		pMesh->CreateFromFile(StaticMeshData[i].StaticMeshFilePath);
		pMesh->pInstance->TextureSize = StaticMeshData[i].TextureSize;
		pMesh->StaticMeshName = StaticMeshData[i].StaticMeshName;
		pMesh->MeshEmitColor = StaticMeshData[i].MeshEmitColor;
		SceneStaticMeshes.push_back(pMesh);
	}
	//gather all vertex
	int SceneVertexCount = 0;
	int CurIndex = 0;
	for (int i=0; i<SceneStaticMeshes.size(); ++i)
	{
		SceneVertexCount += SceneStaticMeshes[i]->pInstance->VertexCount;
	}
	ph_VertexBuffer = new CVertex[SceneVertexCount];
	
	for (int i=0; i<SceneStaticMeshes.size(); ++i)
	{
		memcpy(ph_VertexBuffer + CurIndex
			, SceneStaticMeshes[i]->pInstance->pVertexBuffer
			, SceneStaticMeshes[i]->pInstance->VertexCount*sizeof(CVertex));
		CurIndex += SceneStaticMeshes[i]->pInstance->VertexCount;
		SAFE_DELETE_ARRAY(SceneStaticMeshes[i]->pInstance->pVertexBuffer);
	}
	VertexCount = SceneVertexCount;

	//gather all vertex index
	int SceneVertexIndexCount = 0;
	CurIndex = 0;
	for (int i=0; i<SceneStaticMeshes.size(); ++i)
	{
		SceneVertexIndexCount += SceneStaticMeshes[i]->pInstance->VertexIndexCount;
	}
	ph_VertexIndexBuffer = new int[SceneVertexIndexCount];

	int iCurVertex = 0;
	for (int i=0; i<SceneStaticMeshes.size(); ++i)
	{
		SceneStaticMeshes[i]->pInstance->iStartVertexIndex = CurIndex;
		for(int j=0; j<SceneStaticMeshes[i]->pInstance->VertexIndexCount; ++j)
		{
			SceneStaticMeshes[i]->pInstance->pTriangleIndex[j] += iCurVertex;
		}
		memcpy(ph_VertexIndexBuffer + CurIndex
			, SceneStaticMeshes[i]->pInstance->pTriangleIndex
			, SceneStaticMeshes[i]->pInstance->VertexIndexCount*sizeof(int));
		iCurVertex += SceneStaticMeshes[i]->pInstance->VertexCount;
		CurIndex += SceneStaticMeshes[i]->pInstance->VertexIndexCount;
		SAFE_DELETE_ARRAY(SceneStaticMeshes[i]->pInstance->pTriangleIndex);
	}
	VertexIndexCount = SceneVertexIndexCount;

	//create all Triangle index
	int SceneTriangleIndexCount = SceneVertexIndexCount/3;
	ph_KDTreeTriangleIndexBuffer = new int[SceneTriangleIndexCount];
	for(int i=0; i<SceneTriangleIndexCount; i++)
	{
		ph_KDTreeTriangleIndexBuffer[i] = i;
	}
}

void CSceneManager::BuildCollisionData()
{
	//calc triangles center
	Tuple3f* pTriangleCenter = new Tuple3f[VertexIndexCount/3];
	for(int i=0; i<VertexIndexCount; i+=3)
	{
		pTriangleCenter[i/3] =	(ph_VertexBuffer[ph_VertexIndexBuffer[i]].Position
			+ ph_VertexBuffer[ph_VertexIndexBuffer[i+1]].Position
			+ ph_VertexBuffer[ph_VertexIndexBuffer[i+2]].Position)*0.33333f;
	}

	//begin build KDTree nodes
	std::vector<CKDopNode*>	KDopNodes;
	CKDopNode* TempPadd = new CKDopNode;
	KDopNodes.push_back(TempPadd);

	TempPadd->BuildNode(0
						, VertexIndexCount/3
						, ph_VertexBuffer
						, ph_VertexIndexBuffer
						, ph_KDTreeTriangleIndexBuffer
						, pTriangleCenter
						, KDopNodes);

	SAFE_DELETE_ARRAY(pTriangleCenter);


	KDopNodesCount = KDopNodes.size();
	ph_KDopNodes = new CKDopNode[KDopNodesCount];
	for(int i=0; i<KDopNodes.size(); i++)
	{
		ph_KDopNodes[i] = *KDopNodes[i];
	}

	//clear array data
	for(int i=0; i<KDopNodes.size(); i++)
	{
		delete KDopNodes[i];
	}
	KDopNodes.clear();
}

void CSceneManager::RasterAllTriangles()
{
	for(int i=0; i<SceneStaticMeshes.size(); ++i)
	{
		Tuple2i TextureSize = SceneStaticMeshes[i]->pInstance->TextureSize;
		RasterBufferElement* pElement = new RasterBufferElement[TextureSize.x*TextureSize.y];
		SceneRasterBufferElement.push_back(pElement);
		Tuple2f HalfPixelSize = Tuple2f(0.5f/TextureSize.x, 0.5f/TextureSize.y);

		for(int k=0; k<TextureSize.y; k++)
		{
			for(int j=0; j<TextureSize.x; j++)
			{
				(pElement+int(TextureSize.y*(j))+k)->ComponentAndTriangleIndex = InvalidRasterMark;
			}
		}

		for(int Offset=0; Offset<SceneStaticMeshes[i]->pInstance->VertexIndexCount; Offset+=3)
		{
			int iLocalIndex = SceneStaticMeshes[i]->pInstance->iStartVertexIndex + Offset;
			CVertex* pCurVertex1 = &ph_VertexBuffer[ph_VertexIndexBuffer[iLocalIndex]];
			CVertex* pCurVertex2 = &ph_VertexBuffer[ph_VertexIndexBuffer[iLocalIndex+1]];
			CVertex* pCurVertex3 = &ph_VertexBuffer[ph_VertexIndexBuffer[iLocalIndex+2]];
			Tuple2f UVBoundsMin, UVBoundsMax;
			UVBoundsMin.x = ::min(::min(pCurVertex1->UV.x, pCurVertex2->UV.x), pCurVertex3->UV.x);
			UVBoundsMin.y = ::min(::min(pCurVertex1->UV.y, pCurVertex2->UV.y), pCurVertex3->UV.y);
			UVBoundsMax.x = ::max(::max(pCurVertex1->UV.x, pCurVertex2->UV.x), pCurVertex3->UV.x);
			UVBoundsMax.y = ::max(::max(pCurVertex1->UV.y, pCurVertex2->UV.y), pCurVertex3->UV.y);
			UVBoundsMin = UVBoundsMin*Tuple2f(TextureSize.x, TextureSize.y);
			UVBoundsMax = UVBoundsMax*Tuple2f(TextureSize.x, TextureSize.y);
			for(int m=UVBoundsMin.y; m<UVBoundsMax.y; m++)
			{
				for(int n=UVBoundsMin.x; n<UVBoundsMax.x; n++)
				{
					Tuple2f UV;
					Tuple2f CurUV(n/float(TextureSize.x), m/float(TextureSize.y));
					CurUV += HalfPixelSize;
					if(IsPtInTriangle2D(CurUV, pCurVertex1->UV, pCurVertex2->UV, pCurVertex3->UV, UV))
					{
						(pElement+int(TextureSize.y*(m))+n)->ComponentAndTriangleIndex = iLocalIndex;
						(pElement+int(TextureSize.y*(m))+n)->ElementUV = UV;
					}
					else
					{
						//check sub-pixel
						Tuple2f SubPixelCoord[4];
						SubPixelCoord[0] = CurUV - Tuple2f(HalfPixelSize.x, HalfPixelSize.y);
						SubPixelCoord[1] = CurUV - Tuple2f(-HalfPixelSize.x, HalfPixelSize.y);
						SubPixelCoord[2] = CurUV + Tuple2f(-HalfPixelSize.x, HalfPixelSize.y);
						SubPixelCoord[3] = CurUV + Tuple2f(HalfPixelSize.x, HalfPixelSize.y);
						for(int k=0; k<4; ++k)
						{
							if(IsPtInTriangle2D(SubPixelCoord[0], pCurVertex1->UV, pCurVertex2->UV, pCurVertex3->UV, UV))
							{
								(pElement+int(TextureSize.y*(m))+n)->ComponentAndTriangleIndex = iLocalIndex;
								(pElement+int(TextureSize.y*(m))+n)->ElementUV = UV;
								break;
							}
						}
					}
				}
			}
		}
	}
}

void CSceneManager::BuildLighting()
{
	cudaError_t cudaRes = cudaSuccess;
	for (int i=0; i<d_SceneRasterBufferElement.size(); ++i)
	{
		Tuple2i TextureSize =  SceneStaticMeshes[i]->pInstance->TextureSize;
		
		int ThreadsCount = GetDeviceProp().maxThreadsPerBlock/2;
		int iPassCount = TextureSize.x * TextureSize.y / ThreadsCount;

		SceneProcessLighting<<<iPassCount, ThreadsCount>>>( d_SceneRasterBufferElement[i]
															, pd_VertexBuffer
															//, pd_VertexIndexBuffer
															//, pd_KDTreeTriangleIndexBuffer
															, pd_KDopNodes
															, d_LightMaps[i]
															, pd_ConstantData
															, TextureSize
															, ThreadsCount);
		cudaRes = cudaThreadSynchronize();
	}
	printf("\n Direction lighting complete!\n ");
	for (int j=0; j<RenderConfig.BounceCount; ++j)
	{
		for (int i=0; i<d_SceneRasterBufferElement.size(); ++i)
		{
			Tuple2i TextureSize =  SceneStaticMeshes[i]->pInstance->TextureSize;

			int ThreadsCount = GetDeviceProp().maxThreadsPerBlock/2;
			int iPassCount = TextureSize.x * TextureSize.y / ThreadsCount;

			SceneProcessIndirectionalLighting<<<iPassCount, ThreadsCount>>>( d_SceneRasterBufferElement[i]
																			, pd_VertexBuffer
																			//, pd_VertexIndexBuffer
																			//, pd_KDTreeTriangleIndexBuffer
																			, pd_KDopNodes
																			, d_LightMaps[i]
																			, pd_ConstantData
																			, TextureSize
																			, ThreadsCount);
			cudaRes = cudaThreadSynchronize();
			cudaRes = cudaGetLastError();
		}
		printf("%d InDirection lighting complete!\n ", j);
	}
	
	SceneRasterBufferElement.clear();
}

void CSceneManager::ReleaseDeviceData()
{
	for(int i=0; i<=UsedVertexIndexTextureCount; i++)
	{
		SAFE_FREE_CUDA(pd_VertexIndexTexture[i]);
	}
	for(int i=0; i<=UsedTriangleIndexTextureCount; ++i)
	{
		SAFE_FREE_CUDA(pd_TriangleIndexTexture[i]);
	}

	SAFE_FREE_CUDA(pd_VertexBuffer);

	SAFE_FREE_CUDA(pd_VertexIndexBuffer);

	SAFE_FREE_CUDA(pd_KDTreeTriangleIndexBuffer);

	SAFE_FREE_CUDA(pd_KDopNodes);

	SAFE_FREE_CUDA(pd_ConstantData);

	for (int i=0; i<d_SceneRasterBufferElement.size(); ++i)
	{
		SAFE_FREE_CUDA(d_SceneRasterBufferElement[i]);
		SAFE_FREE_CUDA(d_LightMaps[i]);
	}
	SceneRasterBufferElement.clear();
}

void CSceneManager::DumpLightMaps()
{
	char FilePathBuffer[256];
	for (int i=0; i<d_LightMaps.size(); ++i)
	{
		Tuple2i TextureSize =  SceneStaticMeshes[i]->pInstance->TextureSize;
		unsigned char* pLightMap = new unsigned char[TextureSize.x*TextureSize.y];
		cudaMemcpy(pLightMap, d_LightMaps[i], sizeof(unsigned char)*TextureSize.x*TextureSize.y, cudaMemcpyDeviceToHost);
		sprintf(FilePathBuffer, "%s.raw", SceneStaticMeshes[i]->StaticMeshName.c_str());
		DumpRes(FilePathBuffer, pLightMap, sizeof(char)*TextureSize.x*TextureSize.y);
		SAFE_DELETE_ARRAY(pLightMap);
	}
}

void CSceneManager::ReleaseHostData()
{

}

void CSceneManager::PaserSceneFile(const std::string& FilePath)
{
	TiXmlDocument* pXMLDoc= new TiXmlDocument( FilePath.c_str());
	bool bResult = pXMLDoc->LoadFile();
	if(!bResult)
	{
		printf("Load SceneDesc failed! %s", FilePath.c_str());
		return;
	}
	TiXmlElement* pRoot = pXMLDoc->FirstChildElement("Root");

	DirectionalLights.clear();
	PointLights.clear();
	SpotLights.clear();
	//paser Lights info
	TiXmlElement* pNext = pRoot->FirstChildElement("LightsDesc");
	if(pNext!=NULL)
	{
		//directional lights
		TiXmlElement* pNextDirectionalLights = pNext->FirstChildElement("DirectionalLights");
		if(pNextDirectionalLights)
		{	
			TiXmlElement* pSingleDirectionalLight = pNextDirectionalLights->FirstChildElement("DirectionalLight");
			while(pSingleDirectionalLight)
			{
				CDirectionalLight NewDirectionalLight;
				TiXmlElement* LightColor = pSingleDirectionalLight->FirstChildElement("Color");
				TiXmlElement* LightColorValue = LightColor->FirstChildElement("X");
				NewDirectionalLight.Color.x = atof(LightColorValue->GetText());

				LightColorValue = LightColor->FirstChildElement("Y");
				NewDirectionalLight.Color.y = atof(LightColorValue->GetText());

				LightColorValue = LightColor->FirstChildElement("Z");
				NewDirectionalLight.Color.z = atof(LightColorValue->GetText());


				TiXmlElement* LightDir = pSingleDirectionalLight->FirstChildElement("Direction");
				TiXmlElement* LightDirValue = LightDir->FirstChildElement("X");
				NewDirectionalLight.Dir.x = atof(LightDirValue->GetText());

				LightDirValue = LightDir->FirstChildElement("Y");
				NewDirectionalLight.Dir.y = atof(LightDirValue->GetText());

				LightDirValue = LightDir->FirstChildElement("Z");
				NewDirectionalLight.Dir.z = atof(LightDirValue->GetText());

				NewDirectionalLight.Dir = NewDirectionalLight.Dir.normalize();
				DirectionalLights.push_back(NewDirectionalLight);
				pSingleDirectionalLight = pSingleDirectionalLight->NextSiblingElement("DirectionalLight");
			}
		}

		//point lights info
		TiXmlElement* pNextPointLights = pNext->FirstChildElement("PointLights");
		if(pNextPointLights)
		{	
			TiXmlElement* pSinglePointLight = pNextPointLights->FirstChildElement("PointLight");
			while(pSinglePointLight)
			{
				CPointLight NewPointLight;
				TiXmlElement* LightColor = pSinglePointLight->FirstChildElement("Color");
				TiXmlElement* LightColorValue = LightColor->FirstChildElement("X");
				NewPointLight.Color.x = atof(LightColorValue->GetText());

				LightColorValue = LightColor->FirstChildElement("Y");
				NewPointLight.Color.y = atof(LightColorValue->GetText());

				LightColorValue = LightColor->FirstChildElement("Z");
				NewPointLight.Color.z = atof(LightColorValue->GetText());


				TiXmlElement* LightPosition = pSinglePointLight->FirstChildElement("Position");
				TiXmlElement* LightPositionValue = LightPosition->FirstChildElement("X");
				NewPointLight.Position.x = atof(LightPositionValue->GetText());

				LightPositionValue = LightPosition->FirstChildElement("Y");
				NewPointLight.Position.y = atof(LightPositionValue->GetText());

				LightPositionValue = LightPosition->FirstChildElement("Z");
				NewPointLight.Position.z = atof(LightPositionValue->GetText());

				TiXmlElement* LightCore = pSinglePointLight->FirstChildElement("SphereSize");
				NewPointLight.SphereSize = atof(LightCore->GetText());

				TiXmlElement* LightSize = pSinglePointLight->FirstChildElement("LightBound");
				NewPointLight.LightBound = atof(LightSize->GetText());

				PointLights.push_back(NewPointLight);
				pSinglePointLight = pSinglePointLight->NextSiblingElement("PointLight");
			}
		}
		//spot light
		TiXmlElement* pNextSpotLights = pNext->FirstChildElement("SpotLights");
		if(pNextSpotLights)
		{	
			TiXmlElement* pSingleSpotLight = pNextSpotLights->FirstChildElement("SpotLight");
			while(pSingleSpotLight)
			{
				CSpotLight NewSpotLight;

				TiXmlElement* LightColor = pSingleSpotLight->FirstChildElement("Color");
				TiXmlElement* LightColorValue = LightColor->FirstChildElement("X");
				NewSpotLight.Color.x = atof(LightColorValue->GetText());

				LightColorValue = LightColor->FirstChildElement("Y");
				NewSpotLight.Color.y = atof(LightColorValue->GetText());

				LightColorValue = LightColor->FirstChildElement("Z");
				NewSpotLight.Color.z = atof(LightColorValue->GetText());


				TiXmlElement* LightDir = pSingleSpotLight->FirstChildElement("Direction");
				TiXmlElement* LightDirValue = LightDir->FirstChildElement("X");
				NewSpotLight.Dir.x = atof(LightDirValue->GetText());

				LightDirValue = LightColor->FirstChildElement("Y");
				NewSpotLight.Dir.y = atof(LightDirValue->GetText());

				LightDirValue = LightColor->FirstChildElement("Z");
				NewSpotLight.Dir.z = atof(LightDirValue->GetText());

				TiXmlElement* LightPosition = pSingleSpotLight->FirstChildElement("Position");
				TiXmlElement* LightPostionValue = LightPosition->FirstChildElement("X");
				NewSpotLight.Position.x = atof(LightPostionValue->GetText());

				LightPostionValue = LightPosition->FirstChildElement("Y");
				NewSpotLight.Position.y = atof(LightPostionValue->GetText());

				LightPostionValue = LightPosition->FirstChildElement("Z");
				NewSpotLight.Position.z = atof(LightPostionValue->GetText());

				TiXmlElement* LightSize = pSingleSpotLight->FirstChildElement("SphereSize");
				NewSpotLight.SphereSize = atof(LightSize->GetText());

				SpotLights.push_back(NewSpotLight);
				pSingleSpotLight = pSingleSpotLight->NextSiblingElement("SpotLight");
			}
		}
	}

	pNext = pRoot->FirstChildElement("StaticMeshs");
	if(pNext!=NULL)
	{
		//directional lights
		TiXmlElement* pNextStaticMesh = pNext->FirstChildElement("StaticMesh");
		while(pNextStaticMesh)
		{
			CStaticMeshInfoData MeshInfo;
			TiXmlElement* pStaticMeshFilePath = pNextStaticMesh->FirstChildElement("FilePath");
			MeshInfo.StaticMeshFilePath = pStaticMeshFilePath->GetText();

			TiXmlElement* pStaticMeshName = pNextStaticMesh->FirstChildElement("MeshName");
			MeshInfo.StaticMeshName = pStaticMeshName->GetText();

			TiXmlElement* pTextureSize = pNextStaticMesh->FirstChildElement("TextureSize");
			TiXmlElement* pTextureSizeX = pTextureSize->FirstChildElement("X");
			MeshInfo.TextureSize.x = atoi(pTextureSizeX->GetText());
			TiXmlElement* pTextureSizeY = pTextureSize->FirstChildElement("Y");
			MeshInfo.TextureSize.y = atoi(pTextureSizeY->GetText());

			TiXmlElement* pEmitColor = pNextStaticMesh->FirstChildElement("EmitColor");
			TiXmlElement* pEmitColorX = pEmitColor->FirstChildElement("X");
			MeshInfo.MeshEmitColor.x = atof(pTextureSizeX->GetText());
			TiXmlElement* pEmitColorY = pEmitColor->FirstChildElement("Y");
			MeshInfo.MeshEmitColor.y = atof(pTextureSizeY->GetText());
			TiXmlElement* pEmitColorZ = pEmitColor->FirstChildElement("Z");
			MeshInfo.MeshEmitColor.z = atof(pTextureSizeY->GetText());
			TiXmlElement* pEmitColorW = pEmitColor->FirstChildElement("W");
			MeshInfo.MeshEmitColor.w = atof(pTextureSizeY->GetText());

			StaticMeshData.push_back(MeshInfo);
			pNextStaticMesh = pNextStaticMesh->NextSiblingElement("StaticMesh");
		}
	}
	delete pXMLDoc;
}